package svc.elib.analysis;

import java.io.IOException;
import java.util.LinkedList;

import svc.elib.db.Author;
import svc.elib.db.Database;
import svc.elib.db.Paper;
import svc.elib.util.Distribution;

/**
 * Computes two distributions
 *   1. distribution of the number of papers per author
 *   2. distribution of the activity span per author
 *   3. distribution of the number of authors per paper
 * @author svc
 * @date 15.6.2013
 */
public class AuthorStatistics {
	
	private LinkedList<Author> authors;
	private LinkedList<Paper> papers;
	
	public AuthorStatistics(Database db) {
		authors = db.getAuthors();
		papers = db.getPapers();
		paperDistr();
		activityDistr();
		authorDistr();
	
		numberOfAuthorsPerPaper();
	}
	
	private void authorDistr() {
		LinkedList<Integer> numAuthors = new LinkedList<Integer>();
		for (Paper p : papers) {
			int na = p.getAuthors().size();
			numAuthors.add(na);
		}
		
		System.out.println("\n\nDistribution of the number of authors per paper");
		Distribution d = new Distribution(numAuthors);
		d.printDistr();
		System.out.println("Complementary cummulative distribution... ");
		d.printComplementaryCumulative();
	}
	
	private void paperDistr() {
		Author maxa = null;
		int max = Integer.MIN_VALUE;
		int sum = 0;
		int num = 0;
		
		LinkedList<Integer> numPapers = new LinkedList<Integer>();
		for (Author a : authors) {
			int np = a.getPapers().size();
			numPapers.add(np);
			if (np > max) {
				maxa = a;
				max = np;
			}
			
			sum += np;
			++num;
		}
		
		double avg = (double) sum / (double) num;
		
		double stdDevSum = 0;
		for (Author a : authors) {
			double np = a.getPapers().size();
			stdDevSum += (np - avg) * (np - avg); 
		}
		
		double stdDev = Math.sqrt(stdDevSum / (double) num);
		
		System.out.println("Max author: "); maxa.printFullInfo();
		System.out.println("Average num papers: " + avg);
		System.out.println("Stdandard deviation: " + stdDev);
		
		System.out.println("\n\nDistribution of the number of papers per author");
		Distribution d = new Distribution(numPapers);
		d.printDistr();
		System.out.println("Complementary cummulative distribution... ");
		d.printComplementaryCumulative();
	}
	
	private void numberOfAuthorsPerPaper() {
		
		System.out.println("\n\n\nAuthors per paper, basic data");
		
		LinkedList<Integer> numAuthors = new LinkedList<Integer>();
		int sum = 0;
		int num = 0;
		for (Paper p : papers) {
			int na = p.getAuthors().size();
			numAuthors.add(na);
			System.out.println(na);
			sum += na;
			++num;
		}
		
		double avg = (double) sum / (double) num;
		
		double stdDevSum = 0;
		for (Paper p : papers) {
			double na = (double) p.getAuthors().size();
			stdDevSum += (na - avg) * (na - avg); 
		}
		
		double stdDev = Math.sqrt(stdDevSum / (double) num);
		double CV = avg / stdDev;
		
		//System.out.println("Average value: " + avg);
		//System.out.println("StdDev: " + stdDev);
		//System.out.println("Coefficient of variation: " + CV);
	}
	
	private void activityDistr() {
		LinkedList<Integer> activity = new LinkedList<Integer>();
		for (Author a : authors) {
			int act = a.getActivitySpan();
			if (act > 1)
				activity.add(act);
		}
		
		System.out.println("\n\nDistribution of the activity span per author");
		Distribution d = new Distribution(activity);
		d.printDistr();
		System.out.println("Complementary cummulative distribution... ");
		d.printComplementaryCumulative();
	}
	
	public static void main(String[] args) 
		throws IOException
	{
		Database db = new Database("eLibData.csv", 1932, 2011);
		System.out.println(db.info());
		new AuthorStatistics(db);
	}

}
